[アップデート] AWS Systems Manager Automationでループ実行などの機能が増えました
しばたです。
先日よりAWS Systems Manager Automation (SSM Automation)のランブックにおいてループ実行など幾つかの機能が増えました。
AWSからのアナウンスはこちらになります。
更新点について
AWSのアナウンスが結構ふわっとした内容だったため実際の更新点を把握するまでにかなりの時間を要しました...
具体的な更新内容はSSM全体のドキュメント履歴に記載されており、
aws:loop
アクションの追加aws:updateVariable
アクションの追加- アウトプットデータのキャストサポート
- JSONPathでフィルター式(
([?(expression)])
)のサポート
の4機能となります。
- 参考 : Document history
aws:loop
アクションの追加
1. aws:loop
アクションは名前の通りループ処理を表現するアクションです。
条件を満たすあいだ処理を繰り返すdo while
形式とコレクションの要素を繰り返すfor each
形式の2種類記述することができます。
以下にAWSのドキュメントにある例を転記します。
do while形式
Steps
に繰り返す処理を記述します。
LoopCondition
に継続条件を記述し、記載の例だとLambda関数の実行結果ShouldRetry
の値がtrue
の場合ループを繰り返す事になります。
そして、ループの最大回数をMaxIterations
で指定することもできます。
name: RepeatMyLambdaFunctionUntilOutputIsReturned
action: aws:loop
inputs:
Steps:
- name: invokeMyLambda
action: aws:invokeLambdaFunction
inputs:
FunctionName: LambdaFunctionName
outputs:
- Name: ShouldRetry
Selector: $.Retry
Type: Boolean
LoopCondition:
Variable: "{{ invokeMyLambda.ShouldRetry }}"
BooleanEquals: true
MaxIterations: 3
for each形式
Steps
に繰り返す処理を記述します。
Iterators
に処理を繰り返す元になるコレクションを、コレクション要素の型をIteratorDataType
に記述します。
現在の要素は{{ステップ名.CurrentIteratorValue}}
で取得可能でコレクションの全要素を繰り返せば処理は終了します。
name: stopAllInstancesWithWaitTime
action: aws:loop
inputs:
Iterators: "{{ DescribeInstancesStep.InstanceIds }}"
IteratorDataType: "String"
Steps:
- name: stopOneInstance
action: aws:changeInstanceState
inputs:
InstanceIds:
- "{{stopAllInstancesWithWaitTime.CurrentIteratorValue}}"
CheckStateOnly: false
DesiredState: stopped
- name: wait10Seconds
action: aws:sleep
inputs:
Duration: PT10S
動作確認
今回は手っ取り早く動作確認できるfor each形式のほうを試してみます。
私の検証用AWSアカウントの東京リージョンに以下の内容で新規にランブックを作成します。
description: "Loop action sample"
schemaVersion: '0.3'
mainSteps:
- name: describeInstancesStep
action: aws:executeAwsApi
onFailure: Abort
inputs:
Service: ec2
Api: DescribeInstances
outputs:
- Name: instanceIds
Selector: "$.Reservations..Instances..InstanceId"
Type: StringList
- name: stopAllInstancesWithWaitTime
action: aws:loop
inputs:
Iterators: "{{ describeInstancesStep.instanceIds }}"
IteratorDataType: "String"
Steps:
- name: stopOneInstance
action: aws:changeInstanceState
inputs:
InstanceIds:
- "{{stopAllInstancesWithWaitTime.CurrentIteratorValue}}"
CheckStateOnly: false
DesiredState: stopped
- name: wait10Seconds
action: aws:sleep
inputs:
Duration: PT10S
最初のdescribeInstancesStep
ステップで取得したEC2インスタンスIDのリスト{{ describeInstancesStep.instanceIds }}
を元データとして、stopAllInstancesWithWaitTime
ステップで各要素(各インスタンスID)のインスタンスを停止する内容となっています。
細かい作業手順は端折りますがランブックの作成結果はこんな感じです。
なお、現時点ではaws:loop
アクションはビルダーでサポートされて無いためエディタで直接YAMLを書く必要があります。
(現時点ではビルダーのアクションにaws:loop
は存在せず)
このランブックを実行すると、以下の様にaws:loop
アクションの親ステップとそれに続く各子ステップが順に実行されていきます。
最終的にすべてのステップが完了して処理が終了します。
aws:updateVariable
アクションの追加
2. aws:updateVariable
アクションは指定したドキュメント変数(variables
)の内容を更新するシンプルなものになります。
あくまで内容の更新であり型変換はできませんのでご注意ください。
AWSのドキュメントにある例を転記すると以下の様な使い方をします。割と見たままかと思います。
name: updateStringList
action: aws:updateVariable
inputs:
Name: variable:variable name
Value:
- "1"
- "2"
動作確認
こちらも簡単なランブックを用意して動作確認します。
空StringList
のpayload
変数を更新して終わりという非常にシンプルなものです。
description: "Update value sample"
schemaVersion: '0.3'
variables:
payload:
type: StringList
default: []
mainSteps:
- name: updateStringList
action: aws:updateVariable
inputs:
Name: variable:payload
Value:
- "1"
- "2"
当然ですが実行自体はあっさり成功します。
Variables
が期待した値に更新されていることが分かりますね。
3. アウトプットデータのキャストサポート
従来outputs
の利用においてType
で定義したデータ型とステップを実行して引き渡される実データの型は厳密に一致している必要がありました。
今回の更新により一定のルールに基づいてType
で定義したデータ型へのキャストを試みる様になったとのことです。
ドキュメントによれば以下のキャストが可能とのことです。
実データの型 | 変換可能なデータ型 |
---|---|
String | StringList, Integer, Boolean |
Integer | String, StringList |
Boolean | String, StringList |
要素が1つだけのStringList | String |
要素が1つだけのIntegerList | Integer |
要素が1つだけのBooleanList | Boolean |
あくまでキャストだけであり動的な型変換をするわけでは無いのでご注意ください。
4.JSONPathでフィルター式のサポート
従来ランブックではJSONPathの一部機能をサポートしていました。
今回の更新によりフィルター式(([?(<expression>)])
)を追加でサポートしたとのことです。
上記ドキュメントにある例を出すと、例えばEC2のDescribeInstances
APIを実行した結果に対して
$.Reservations..Instances[?(@.State.Name == "running")]
といった記述をすることで起動中のインスタンスのみを抽出対象にすることができる様になりました。
動作確認
簡単なランブックを用意して動作確認します。
動作中(running
)のEC2インスタンスIDを列挙するだけのものになります。
description: "JSONPath filter sample"
schemaVersion: '0.3'
mainSteps:
- name: describeInstancesStep
action: aws:executeAwsApi
onFailure: Abort
inputs:
Service: ec2
Api: DescribeInstances
outputs:
- Name: instanceIds
Selector: "$.Reservations..Instances[?(@.State.Name == 'running')].InstanceId"
Type: StringList
予め1台だけEC2インスタンスを起動しておき実行した結果はこんな感じです。
これだけだと分かりにくいでしょうが、実際に意図した通りフィルターされています。
aws:createOpsTask
アクションについて
余談 : 今回の検証をしている際に気が付いたのですが、ランブックのビルダーでドキュメントに記載の無いaws:createOpsTask
アクションの存在を確認しました。
ただ、現状このアクションを選択してもUIに変化が無く実用するのは難しそうです。
名前からしてAWS Systems Manager OpsCenterのOpsItemsを追加するものっぽいですが確証は無いので今後の情報に期待しましょう。
最後に
以上となります。
SSM Automationランブックの記述がより柔軟にできる更新です。
機会があれば活用してみてください。